home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-10-18 | 5.6 KB | 235 lines | [TEXT/MPCC] |
- /*
- File: Int64.c
-
- Contains: 64-bit math class
-
- Written by: Dave Owens, tweeked by Andy Nicholas and Chris Bingham
-
- Copyright: © 1994-1995 by Apple Computer, Inc., all rights reserved.
-
- <3> 3/20/95 andy
- */
-
- #ifdef MWTRACEBACKTABLES
- #pragma traceback on
- #endif
-
- #include "Int64.h"
-
- #pragma segment LookupSizes
-
- //========================================================================================
- // CLASS Int64
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // Int64::IntuitOtherOperand:
- //
- // IntuitOtherOperand
- //
- // This function decodes the input data and makes sure that it is packaged into
- // an Int64.
- //----------------------------------------------------------------------------------------
- const Int64* Int64::IntuitOtherOperand(short operation, const void* input, Int64* otherStorage)
- {
- int type = operation & typeMask;
- if (type == typeOtherIsInt64)
- return (const Int64*) input;
-
- otherStorage->fHigh32 = 0;
-
- switch (type)
- {
- case typeOtherIsInt:
- {
- if (*(const int*)input < 0)
- otherStorage->fHigh32 = -1;
-
- otherStorage->fLow32 = *(const int*) input;
- break;
- }
- case typeOtherIsLong:
- {
- if (*(const long*)input < 0)
- otherStorage->fHigh32 = -1;
-
- otherStorage->fLow32 = *(const unsigned long*) input;
- break;
- }
-
- default:
- otherStorage->fLow32 = *(const unsigned long*) input;
- }
-
- return otherStorage;
- } // Int64::IntuitOtherOperand
-
-
- //----------------------------------------------------------------------------------------
- // Int64::Operation:
- //----------------------------------------------------------------------------------------
- Int64 Int64::Operation(short operation, const void* input) const
- {
- Int64 sourceStorage;
-
- Int64 main;
- main.fHigh32 = fHigh32;
- main.fLow32 = fLow32;
-
- const Int64* other = IntuitOtherOperand(operation, input, &sourceStorage);
- unsigned long temp;
-
- switch (operation & verbMask)
- {
- case verbAssign:
- {
- main.fHigh32 = other->fHigh32;
- main.fLow32 = other->fLow32;
- }
- break;
-
- case verbAdd:
- {
- temp = main.fLow32 + other->fLow32;
- if ((temp < main.fLow32) && (temp < other->fLow32))
- ++main.fHigh32; // catch overflow
- main.fLow32 = temp;
- main.fHigh32 += other->fHigh32;
- }
- break;
-
- case verbSubtract:
- {
- if (other->fLow32 > main.fLow32) // catch underflow
- --main.fHigh32;
- main.fLow32 -= other->fLow32;
- main.fHigh32 -= other->fHigh32;
- }
- break;
-
- //
- // ••• this code needs to be replaced by something that works,
- // preferably a call to the 64-bit math library!
- //
- case verbMultiply:
- {
- if ((main == Int64(0L) ) || (*other == Int64(0L) ))
- main = 0;
- else
- {
- // assumes a maximum multiply of 48 bits * 31 bits
- unsigned short a3 = (main.fHigh32 & 0xFFFF);
- unsigned short a2 = (main.fLow32 & 0xFFFF0000) >> 16;
- unsigned short a1 = (main.fLow32 & 0xFFFF);
- unsigned short b2 = (other->fLow32 & 0xFFFF0000) >> 16;
- unsigned short b1 = (other->fLow32 & 0xFFFF);
-
- main = (unsigned long) ((a3 * b2));
- main <<= 16;
- main += (unsigned long) ((a3 * b1) + (a2 * b2));
- main <<= 16;
- main += (unsigned long) ((a2 * b1) + (a1 * b2));
- main <<= 16;
- main += (unsigned long)(a1 * b1);
- }
- }
- break;
-
- //
- // ••• this code needs to be replaced by something that works,
- // preferably a call to the 64-bit math library!
- //
- case verbDivide:
- {
- if ((main == Int64(0L) ) || (*other == Int64(0L) ))
- main = 0;
- else
- {
- // other->fLow32 is the denominator
- long numerator = main.fHigh32;
- Int64 times;
- times.fHigh32 = numerator / other->fLow32;
-
- numerator -= times.fHigh32 * other->fLow32;
- numerator = (numerator << 16) | (main.fLow32 >> 16);
- times.fLow32 = numerator / other->fLow32;
-
- numerator -= times.fLow32 * other->fLow32;
- numerator = (numerator << 16) | (main.fLow32 & 0xFFFF);
- times.fLow32 <<= 16;
- times.fLow32 += numerator / other->fLow32;
-
- main.fHigh32 = times.fHigh32;
- main.fLow32 = times.fLow32;
- }
- }
- break;
-
- case verbShiftRight:
- {
- // ASSERT(*other < 64);
- temp = other->fLow32;
- main.fLow32 = (main.fHigh32 << (32 - temp)) | (main.fLow32 >> temp);
- main.fHigh32 = main.fHigh32 >> temp;
- }
- break;
-
- case verbShiftLeft:
- {
- // ASSERT(*other < 64);
- temp = other->fLow32;
- main.fHigh32 = (main.fHigh32 << temp) | (main.fLow32 >> (32 - temp));
- main.fLow32 = main.fLow32 << temp;
- }
- break;
-
- default:
- // ASSERT(false);
- break;
- }
-
- return main;
- }
-
- //----------------------------------------------------------------------------------------
- // Int64::Comparison:
- //----------------------------------------------------------------------------------------
- Boolean Int64::Comparison(short comparison, const void* input) const
- {
- Int64 otherStorage;
-
- const Int64* other = IntuitOtherOperand(comparison, input, &otherStorage);
- Boolean result = false;
- Boolean negateResult = false;
-
- switch (comparison & cmpMask)
- {
- case cmpNotEqual:
- negateResult = true;
- case cmpEqual:
- result = (fHigh32 == other->fHigh32) && (fLow32 == other->fLow32);
- break;
-
- case cmpGreaterOrEqual:
- negateResult = true;
- case cmpLess:
- result = (fHigh32 < other->fHigh32) ||
- ((fHigh32 == other->fHigh32) && (fLow32 < other->fLow32));
- break;
-
- case cmpLessOrEqual:
- negateResult = true;
- case cmpGreater:
- result = (fHigh32 > other->fHigh32) ||
- ((fHigh32 == other->fHigh32) && (fLow32 > other->fLow32));
- break;
-
- default:
- // ASSERT(false);
- break;
- }
-
- return result ^ negateResult;
- } // Int64::Comparison
-
-